package com.ctshk.rpc.payment.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.utils.Assert;
import com.ctshk.rpc.payment.dto.RefundDetailsDTO;
import com.ctshk.rpc.payment.entity.PayRecord;
import com.ctshk.rpc.payment.entity.RefundRecord;
import com.ctshk.rpc.payment.enums.PayOrderStatus;
import com.ctshk.rpc.payment.enums.PaymentMethodClass;
import com.ctshk.rpc.payment.enums.RefundStatus;
import com.ctshk.rpc.payment.mapper.PayRecordMapper;
import com.ctshk.rpc.payment.mapper.RefundRecordMapper;
import com.ctshk.rpc.payment.service.IRefundRecordService;
import com.ctshk.rpc.payment.strategy.PayContext;
import com.ctshk.rpc.payment.utils.PayUtil;
import org.apache.dubbo.config.annotation.DubboService;

import javax.annotation.Resource;
import java.util.Map;

/**
 * <p>
 * 退款记录 服务实现类
 * </p>
 *
 * @author hef
 * @since 2021-05-07
 */
@DubboService
public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements IRefundRecordService {
    @Resource
    private PayRecordMapper recordMapper;
    @Resource
    private RefundRecordMapper refundRecordMapper;

    @Override
    public RefundDetailsDTO getRefundDetail(String orderNumber, String refundNumber) {
        PayRecord payRecord = recordMapper.selectByOrderId(Long.valueOf(orderNumber));
        Assert.nonNull(payRecord, SystemError.PAY_22004);
        //获取本地退款记录
        RefundRecord refundRecord = refundRecordMapper.selectByOrderAndRefundNumber(orderNumber, refundNumber);
        Assert.nonNull(refundRecord, SystemError.PAY_22013);
        //如果是已经处理了的 返回本地数据
        if (!RefundStatus.PROCESSING.getStatus().equals(refundRecord.getRefundStatus())) {
            RefundDetailsDTO dto = new RefundDetailsDTO();
            dto.setOrderNumber(refundRecord.getOrderNumber());
            dto.setRefundNumber(refundRecord.getRefundNumber());
            dto.setRefundAmount(refundRecord.getRefundAmt());
            dto.setRefundStatus(RefundStatus.getByStatus(refundRecord.getRefundStatus()));
            dto.setRefundTime(refundRecord.getRefundTime());
            dto.setCurrency(refundRecord.getCurrency());
            return dto;
        }
        RefundDetailsDTO refundDetail = PayContext.getRefundDetail(orderNumber, refundNumber,
                PaymentMethodClass.getClassByCode(payRecord.getPaymentMethod()));
        Assert.nonNull(refundDetail, SystemError.PAY_22013);
        //避免本地记录和远程数据不一致
        if (refundRecord == null ||
                !refundDetail.getRefundStatus().getStatus().equals(refundRecord.getRefundStatus())) {
            RefundRecord updateRecord = new RefundRecord();
            updateRecord.setOrderNumber(refundDetail.getOrderNumber());
            updateRecord.setRefundNumber(refundDetail.getRefundNumber());
            updateRecord.setRefundAmt(refundDetail.getRefundAmount());
            updateRecord.setCurrency(refundDetail.getCurrency());
            updateRecord.setRefundStatus(refundDetail.getRefundStatus().getStatus());
            updateRecord.setRefundTime(refundDetail.getRefundTime());
            updateRecord.setIsDeleted(0);
            updateRecord.setId(refundRecord != null ? refundRecord.getId() : IdWorker.getId());
            saveOrUpdate(updateRecord);
            //已退款的话需要同步到付款记录
            if (RefundStatus.SUCCESS.getStatus().equals(updateRecord.getRefundStatus())) {
                recordMapper.update(new PayRecord().setOrderStatus(PayOrderStatus.REFUNDED.getStatus()),
                        Wrappers.<PayRecord>lambdaUpdate().eq(PayRecord::getOrderNumber, refundDetail.getOrderNumber()));
            }
        }
        return refundDetail;
    }

    @Override
    public Object refundNotify(Map<String, String> parameterMap) {
        String refundNumber = PayUtil.getRefundNumber(parameterMap);
        RefundRecord refundRecord = refundRecordMapper.selectByRefundNumber(refundNumber);
        Assert.nonNull(refundRecord, SystemError.PAY_22013);
        PayRecord payRecord = recordMapper.selectByOrderId(Long.valueOf(refundRecord.getOrderNumber()));
        Assert.nonNull(payRecord, SystemError.PAY_22004);
        Object o = PayContext.refundNotify(parameterMap, PaymentMethodClass.getClassByCode(payRecord.getPaymentMethod()));
        return o;
    }
}
